package com.atguigu.gmall.activity.receiver;

import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

@Component
public class SeckillReceiver{

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private SeckillGoodsService seckillGoodsService;

    //监听定时任务，定时将mysql中的秒杀数据导入到redis中
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = MqConst.QUEUE_TASK_1,durable = "true",autoDelete = "false"),
                                            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),
                                            key = {MqConst.ROUTING_TASK_1}))
    public void importDataToRedis(String msg, Message message, Channel channel){
        try {
            System.out.println(msg);

            //查出数据库中当天的秒杀商品
            QueryWrapper<SeckillGoods> seckillGoodsQueryWrapper = new QueryWrapper<>();
            //状态值为1，表示该商品参与秒杀活动
            seckillGoodsQueryWrapper.eq("status","1");
            //库存剩余数量要大于0
            seckillGoodsQueryWrapper.gt("stock_count",0);

            //秒杀开始时间在当天的商品
            //select  DATE_FORMAT(start_time,'%Y-%m-%d') from seckill_goods;  格式：yyyy-MM-dd
            seckillGoodsQueryWrapper.eq("DATE_FORMAT(start_time,'%Y-%m-%d')", DateUtil.formatDate(new Date()));
            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(seckillGoodsQueryWrapper);
            //将当天参与秒杀活动的商品放入缓存中
            for (SeckillGoods seckillGoods : seckillGoodsList) {
                //判断缓存中是否有该商品
                Boolean result = redisTemplate.opsForHash().hasKey(RedisConst.SECKILL_GOODS, seckillGoods.getSkuId().toString());
                if(result){
                    continue;
                }
                //将商品放入缓存
                redisTemplate.opsForHash().put(RedisConst.SECKILL_GOODS,seckillGoods.getSkuId().toString(),seckillGoods);

                //将商品数量放入redis-list
                for (Integer i = 0; i < seckillGoods.getStockCount(); i++) {
                    //key=seckill:stock:skuId  value:skuId
                    redisTemplate.opsForList().leftPush(RedisConst.SECKILL_STOCK_PREFIX + seckillGoods.getSkuId(),seckillGoods.getSkuId());
                }
                //使用redis的订阅/发布，同步状态位 初始状态为 skuId:1
                    redisTemplate.convertAndSend("seckillpush",seckillGoods.getSkuId()+":1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    //监听秒杀订单 校验过下单码和状态位
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = MqConst.QUEUE_SECKILL_USER,durable = "true",autoDelete = "false"),
                                            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_SECKILL_USER),
                                            key = {MqConst.ROUTING_SECKILL_USER}))
    public void seckillUser(UserRecode userRecode,Message message,Channel channel){
        try {
            if(userRecode!=null){
                //预下单处理
                seckillGoodsService.seckillOrder(userRecode.getSkuId(),userRecode.getUserId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}
